package com.ev.apis.controller.asl;

import cn.afterturn.easypoi.entity.vo.TemplateExcelConstants;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.view.PoiBaseView;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.ev.apis.model.DsResultResponse;
import com.ev.asl.constant.AslConstant;
import com.ev.asl.dao.CheckResultDao;
import com.ev.asl.dao.CheckResultDetailDao;
import com.ev.asl.domain.CheckResultDO;
import com.ev.asl.domain.CheckResultDetailDO;
import com.ev.asl.domain.MoldingDailyDO;
import com.ev.asl.domain.MoldingProductionInstructionDO;
import com.ev.asl.dto.MoldingDailyDto;
import com.ev.asl.service.CheckResultService;
import com.ev.asl.service.MoldingBarcodeService;
import com.ev.asl.service.MoldingDailyService;
import com.ev.asl.service.MoldingProductionInstructionService;
import com.ev.asl.vo.CheckResultDetail2VO;
import com.ev.custom.domain.NoticeDO;
import com.ev.custom.service.NoticeService;
import com.ev.framework.annotation.EvApiByToken;
import com.ev.framework.config.Constant;
import com.ev.framework.config.ConstantForMES;
import com.ev.framework.utils.*;
import com.ev.mes.service.CheckProjectService;
import com.ev.mes.vo.WorkTimeVO;
import com.ev.system.domain.UserDO;
import com.ev.system.service.UserService;
import com.google.common.collect.Maps;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 成型日报API
 * @author 姚家乐
 * @since 2021/5/26 9:57
 */
@Api(value = "/", tags = "成型日报API")
@RestController
@Slf4j
public class MoldingDailyApiController {

    @Autowired
    private MoldingDailyService moldingDailyService;

    @Autowired
    private CheckResultDao checkResultDao;
    @Autowired
    private CheckResultDetailDao checkResultDetailDao;


    @Autowired
    private CheckResultService checkResultService;
    @Autowired
    private CheckProjectService checkProjectService;

    @Autowired
    private MoldingBarcodeService moldingBarcodeService;
    @Autowired
    private MoldingProductionInstructionService moldingProductionInstructionService;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private UserService userService;

    /**
     * 保存成型生产日报信息
     *
     * @date 2019-11-27
     * @author gumingjie
     */
    @Transactional(rollbackFor = Exception.class)
    @EvApiByToken(value = "/apis/MoldingDaily/save", method = RequestMethod.POST, apiTitle = "保存成型生产日报信息")
    @ApiOperation("保存生产日报信息")
    public R save(MoldingDailyDto dto) {
//        Map<String,Object> param = new HashMap<>();
//        param.put("isChooseShow",AslConstant.ONE);
//        param.put("instructionId",dto.getMpiId());
////        Map<String,Object> resu = checkResultService.listForMap(param).get(0);
//        List<Map<String, Object>> list = checkResultService.listForMap(param);
//        if (ObjectUtils.isEmpty(list) || list.size() == 0){
//            return R.error("该指示书不存在首检报告，不允许新增日报");
//        }
//        Map<String,Object> resu = list.get(0);
//
//        Integer n = Integer.parseInt(String.valueOf(resu.get("result")));
//        if (AslConstant.ONE.equals(n)){
//            return R.error("选中的指示书首检不合格，不允许新增日报");
        Map<String, Object> result2 = Maps.newHashMapWithExpectedSize(1);
        if (ObjectUtils.isEmpty(dto.getInstructionQty())){
            return R.error("请输入指示数量");
        }
//        }
        MoldingProductionInstructionDO instructionDO = moldingProductionInstructionService.get(dto.getMpiId());
        if (ObjectUtils.isEmpty(instructionDO)){
            return R.error("该生产指示已被删除");
        }

        MoldingProductionInstructionDO instructionDO2 = moldingProductionInstructionService.get(dto.getMpiId2());
        if (ObjectUtils.isEmpty(instructionDO2)){
            return R.error("该生产指示2已被删除");
        }

        Map<String,Object> param = new HashMap<>();
        param.put("isChooseShow",AslConstant.ONE);
        param.put("instructionId",dto.getMpiId());
//        List<Map<String, Object>> list = checkResultService.listForMap(param);

        //首检和成型日报不强关联
//        if (ObjectUtils.isEmpty(list)){
//            return R.error("该指示书不存在首检报告，不允许新增日报");
//        }
//
//        CheckResultDO resultDO = new CheckResultDO();
//        resultDO.setInstructionId(dto.getMpiId());
//        resultDO.setInstructionNo(dto.getMpiNo());
//        resultDO.setProductionDate(dto.getIndicateDate());
//        resultDO.setProductId(instructionDO.getMaterielId());
//        resultDO.setProduct(instructionDO.getMaterielName());
//        resultDO.setInstructionQty(dto.getInstructionQty());


        //判断是否有今天的C，有就C就返回失败，没有C就继续；  判断是否有今天的AB，没有就生成abc
//        Map<String, Object> params = Maps.newHashMapWithExpectedSize(5);
//        params.put("materielId", instructionDO.getMaterielId());
//        List<CheckResultDetail2VO> checkProjects = checkProjectService.list3(params);
        if (ObjectUtils.isEmpty(instructionDO.getMaterielId())){
            System.out.println("==================新增成型日报，没有物料id");
            return R.error("操作失败，请联系管理员");
        }
//        if (dto.getMGroup().equals(0) && !indicateDate.equals(dailyDate)){
//            List<Map<String, Object>> todayResultA = list.stream().filter(result -> !ObjectUtils.isEmpty(result.get("productionDate")) && DateUtils.format((Date) result.get("productionDate")).equals(dailyDate)
//                    && !ObjectUtils.isEmpty(result.get("group")) && result.get("group").toString().equals("0")
//                    && !ObjectUtils.isEmpty(result.get("type")) && result.get("type").toString().equals("1")).collect(Collectors.toList()
//            );
//            if (!ObjectUtils.isEmpty(todayResultA)){
//                return R.error("该指示书今天已经生成A组成型日报，不允许新增日报");
//            }
////            checkResult(checkProjects,dto.getMGroup(),resultDO);
//        }
//        if (dto.getMGroup().equals(1) && !indicateDate.equals(dailyDate)){
//            List<Map<String, Object>> todayResultB = list.stream().filter(result -> !ObjectUtils.isEmpty(result.get("productionDate")) && DateUtils.format((Date) result.get("productionDate")).equals(dailyDate)
//                    && !ObjectUtils.isEmpty(result.get("group")) && result.get("group").toString().equals("1")).collect(Collectors.toList());
//            if (!ObjectUtils.isEmpty(todayResultB)){
//                return R.error("该指示书今天已经生成B组成型日报，不允许新增日报");
//            }
////            checkResult(checkProjects,dto.getMGroup(),resultDO);
//
//        }
//        if (dto.getMGroup().equals(2) && !indicateDate.equals(dailyDate)){
//            List<Map<String, Object>> todayResultC = list.stream().filter(result -> !ObjectUtils.isEmpty(result.get("productionDate")) && DateUtils.format((Date) result.get("productionDate")).equals(dailyDate)
//                    && !ObjectUtils.isEmpty(result.get("group")) && result.get("group").toString().equals("2")).collect(Collectors.toList());
//            if (!ObjectUtils.isEmpty(todayResultC)){
//                return R.error("该指示书今天已经生成C组成型日报，不允许新增日报");
//            }
////            checkResult(checkProjects,dto.getMGroup(),resultDO);
//        }

        //对每组第一次生成日报时，可以超出指示数量，第一次以后就不能超出指数数量
        if (ObjectUtils.isEmpty(dto.getProductionQty())) dto.setProductionQty(BigDecimal.ZERO);
        switch (dto.getMGroup()) {
            case 0:
                if (dto.getProductionQty().compareTo(instructionDO.getAGroupResidue()) >0 ){
                    if (!instructionDO.getAUpdateFirst().equals(0)){
                        return R.error("指示数量超出指示剩余量");
                    }else{
                        instructionDO.setAGroupResidue(new BigDecimal(0));
                    }
                }else {
                    instructionDO.setAGroupResidue(instructionDO.getAGroupResidue().subtract(dto.getProductionQty()));
                }
                instructionDO.setAUpdateFirst(1);
                break;
            case 1:
                if (dto.getProductionQty().compareTo(instructionDO.getBGroupResidue()) >0 ){
                    if (!instructionDO.getBUpdateFirst().equals(0)){
                        return R.error("指示数量超出指示剩余量");
                    }else{
                        instructionDO.setBGroupResidue(new BigDecimal(0));
                    }
                }else {
                    instructionDO.setBGroupResidue(instructionDO.getBGroupResidue().subtract(dto.getProductionQty()));
                }
                instructionDO.setBUpdateFirst(1);
                break;
            case 2:
                if (dto.getProductionQty().compareTo(instructionDO.getCGroupResidue()) >0 ){
                    if (!instructionDO.getCUpdateFirst().equals(0)){
                        return R.error("指示数量超出指示剩余量");
                    }else{
                        instructionDO.setCGroupResidue(new BigDecimal(0));
                    }
                }else {
                    instructionDO.setCGroupResidue(instructionDO.getCGroupResidue().subtract(dto.getProductionQty()));
                }
                instructionDO.setCUpdateFirst(1);
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + dto.getMGroup());
        }
        if (ObjectUtils.isEmpty(dto.getProductionQty())) dto.setProductionQty(BigDecimal.ZERO);
        if (ObjectUtils.isEmpty(dto.getInspectionQty())) dto.setInspectionQty(BigDecimal.ZERO);
        if (ObjectUtils.isEmpty(dto.getInstructionQty())) dto.setInstructionQty(BigDecimal.ZERO);
        if (moldingDailyService.save(dto) > 0) {
            result2.put("id", dto.getId());

            moldingProductionInstructionService.update(instructionDO);
//            resultDO.setDailyNo(dto.getMpiNo());
//            resultDO.setDailyId(dto.getId());
//            String batchNo = (ObjectUtil.isEmpty(dto.getLotNoEnd()) ? "" : dto.getLotNoEnd()) + (ObjectUtil.isEmpty(dto.getLotNoStart()) ? "" : dto.getLotNoStart());
//            resultDO.setBatchNo(batchNo);
//            if (!ObjectUtils.isEmpty(checkProjects)){
//                checkResult(checkProjects,dto.getMGroup(),resultDO);
//            }
            return R.ok(result2);
        }
        return R.error();
    }

    /**
     *
     * @param checkResultDetail2VOS
     * @param type 组别
     */
    private void checkResult(List<CheckResultDetail2VO> checkResultDetail2VOS,Integer type, CheckResultDO resultDO){
        List<CheckResultDetailDO> detailDOS = new ArrayList<>();
//        resultDO.setQualityInspectorId(ShiroUtils.getUserId());
//        resultDO.setQualityInspectorName(ShiroUtils.getUser().getName());
        resultDO.setStatus(AslConstant.NO);
        resultDO.setDelFlag(AslConstant.NO);
        resultDO.setBillDate(new Date());
        resultDO.setType(AslConstant.YES);


        String prefix = DateFormatUtil.getWorkOrderno(ConstantForMES.CHECK_PLAN_JCCJ, new Date());
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(3);
        params.put("checkNo", prefix);
        params.put("offset", 0);
        params.put("limit", 1);
        List<CheckResultDO> checkResultDOList = checkResultDao.list(params);
        String suffix = null;
        if (checkResultDOList.size() > 0) {
            suffix = checkResultDOList.get(0).getCheckNo();
        }
        resultDO.setCheckNo(DateFormatUtil.getWorkOrderno(prefix, suffix));
        resultDO.setIsChooseShow(1);
        resultDO.setGroup(type);
        checkResultDao.save(resultDO);
        checkResultDetail2VOS.forEach(check -> {
            CheckResultDetailDO detailDO = new CheckResultDetailDO();
            detailDO.setCheckItemId(check.getCheckItemId());
            detailDO.setCheckTypeId(check.getCheckTypeId());
            detailDO.setCheckItem(check.getCheckItem());
            detailDO.setSize(check.getSize());
            detailDO.setSample(check.getSample());
            detailDO.setCheckWay(check.getCheckWay());
            detailDO.setFormula(check.getFormula());
            detailDO.setSpecification(check.getSpecification());
            detailDO.setMainId(resultDO.getId());
            detailDOS.add(detailDO);
        });
//        if (type.equals(2)){
//
//            resultDO.setType(AslConstant.NO);
//            resultDO.setGroup(0);
//            resultDO.setCheckNo(DateFormatUtil.getWorkOrderno(prefix, resultDO.getCheckNo()));
//            checkResultDao.save(resultDO);
//            checkResultDetail2VOS.forEach(check -> {
//                CheckResultDetailDO detailDO = new CheckResultDetailDO();
//                detailDO.setCheckItemId(check.getCheckItemId());
//                detailDO.setCheckTypeId(check.getCheckTypeId());
//                detailDO.setCheckItem(check.getCheckItem());
//                detailDO.setCheckWay(check.getCheckWay());
//                detailDO.setFormula(check.getFormula());
//                detailDO.setSpecification(check.getSpecification());
//                detailDO.setMainId(resultDO.getId());
//                detailDOS.add(detailDO);
//            });
//            resultDO.setGroup(1);
//            resultDO.setCheckNo(DateFormatUtil.getWorkOrderno(prefix, resultDO.getCheckNo()));
//            checkResultDao.save(resultDO);
//            checkResultDetail2VOS.forEach(check -> {
//                CheckResultDetailDO detailDO = new CheckResultDetailDO();
//                detailDO.setCheckItemId(check.getCheckItemId());
//                detailDO.setCheckTypeId(check.getCheckTypeId());
//                detailDO.setCheckItem(check.getCheckItem());
//                detailDO.setCheckWay(check.getCheckWay());
//                detailDO.setFormula(check.getFormula());
//                detailDO.setSpecification(check.getSpecification());
//                detailDO.setMainId(resultDO.getId());
//                detailDOS.add(detailDO);
//            });
//        }
        checkResultDetailDao.batchSave(detailDOS);
        checkResultService.sendCheckMessage(resultDO.getId());

    }
    /**
     * 查看成型日报详情
     *
     * @date 2019-11-27
     * @author gumingjie
     */
    @EvApiByToken(value = "/apis/MoldingDaily/detail", method = RequestMethod.POST, apiTitle = "查看成型日报详情")
    @ApiOperation("查看成型日报详情")
    public R detail(@ApiParam(value = "成型日报Id", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
        return R.ok(moldingDailyService.getDetailInfo(id));
    }

//    /**
//     *成型日报导出
//     *
//     * @return ApiResult
//     */
//    @ApiOperation(value = "成型日报导出")
//    @GetMapping("/apis/exportExcel/checkOut222")
//    public void downloadExport(HttpServletResponse response,
//                               @ApiParam(value = "主表ID", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
//        moldingDailyService.downloadExport(response,id);
//    }
    /**
     *成型日报导出
     *
     * @return ApiResult
     */
    @ApiOperation(value = "成型日报导出")
    @GetMapping("/apis/MoldingDaily/recordExport")
    public void downloadExport(HttpServletResponse response,
                               @ApiParam(value = "主表ID", required = true) @RequestParam(value = "id", defaultValue = "") Long id) {
        moldingDailyService.downloadExport(response,id);
    }

    /**
     * 修改成型日报
     * @param dto
     * @return
     */
    @EvApiByToken(value = "/apis/MoldingDaily/update", method = RequestMethod.POST, apiTitle = "修改成型日报")
    @ApiOperation("修改成型日报")
    public R update(MoldingDailyDto dto) {
        MoldingDailyDO moldingDailyDO = moldingDailyService.get(dto.getId());
        MoldingProductionInstructionDO instructionDO = moldingProductionInstructionService.get(dto.getMpiId());
//        String batchNo = (ObjectUtil.isEmpty(dto.getLotNoEnd()) ? "" : dto.getLotNoEnd()) + (ObjectUtil.isEmpty(dto.getLotNoStart()) ? "" : dto.getLotNoStart());
//        checkResultDao.get()
//        if (!ObjectUtils.isEmpty(batchNo)){
//
//            resultDO.setBatchNo(batchNo);
//        }
        if (!(AslConstant.MoldingDailyStatus.PLAN.getType().equals(moldingDailyDO.getStatus()) || AslConstant.MoldingDailyStatus.SUBMITTED.getType().equals(dto.getStatus()))) {
            return R.error("该状态不能修改！");
        }
        switch (dto.getMGroup()) {
            case 0:
                BigDecimal subtractA = dto.getProductionQty().subtract(moldingDailyDO.getProductionQty());
                instructionDO.setAGroupResidue(instructionDO.getAGroupResidue().subtract(subtractA));
                break;
            case 1:
                BigDecimal subtractB = dto.getProductionQty().subtract(moldingDailyDO.getProductionQty());
                instructionDO.setBGroupResidue(instructionDO.getBGroupResidue().subtract(subtractB));
                break;
            case 2:
                BigDecimal subtractC = dto.getProductionQty().subtract(moldingDailyDO.getProductionQty());
                instructionDO.setCGroupResidue(instructionDO.getCGroupResidue().subtract(subtractC));
                break;
        }
        moldingProductionInstructionService.update(instructionDO);
        if(ObjectUtils.isEmpty(dto.getBadSituation())){
            dto.setBadSituation("[]");
        }
        if(ObjectUtils.isEmpty(dto.getInspectionQty())){
            dto.setInspectionQty(new BigDecimal(0));
        }
        int update = moldingDailyService.update(dto);
        if (update > 0) {
            return R.ok();
        }
        return R.error();
//        if (AslConstant.MoldingDailyStatus.PLAN.getType().equals(moldingDailyDO.getStatus())) {
//            int update = moldingDailyService.update(dto);
//            if (update > 0) {
//                return R.ok();
//            }
//            return R.error();
//        }
//        return R.error("该状态不能修改！");
    }

    /**
     * 删除
     */
    @EvApiByToken(value = "/apis/MoldingDaily/batchRemove", method = RequestMethod.GET, apiTitle = "删除成型日报")
    @ApiOperation("删除成型日报")
    @Transactional(rollbackFor = Exception.class)
    public R batchRemove(@RequestParam("ids") Long[] ids) {
        //前端现在做了限制，一次只能删除一个记录
        MoldingDailyDO dto = moldingDailyService.get(ids[0]);
        MoldingProductionInstructionDO instructionDO = moldingProductionInstructionService.get(dto.getMpiId());
        switch (dto.getMGroup()) {
            case 0:
                instructionDO.setAGroupResidue(instructionDO.getAGroupResidue().add(dto.getProductionQty()));
                break;
            case 1:
                instructionDO.setBGroupResidue(instructionDO.getBGroupResidue().add(dto.getProductionQty()));
                break;
            case 2:
                instructionDO.setCGroupResidue(instructionDO.getCGroupResidue().add(dto.getProductionQty()));
                break;
        }
        moldingProductionInstructionService.update(instructionDO);
        int remove = moldingDailyService.batchRemove(ids);
        if (remove > 0) {
            return R.ok("删除成功");
        }
        return R.error("删除失败");
    }

    /**
     * 删除
     */
    @EvApiByToken(value = "/apis/MoldingDaily/remove", method = RequestMethod.GET, apiTitle = "删除成型日报")
    @ApiOperation("删除成型日报")
    public R remove(@RequestParam("id") Long id) {
        MoldingDailyDO moldingDailyDO = moldingDailyService.get(id);
        if (AslConstant.MoldingDailyStatus.PLAN.getType()
            .equals(moldingDailyDO.getStatus())) {
            int remove = moldingDailyService.remove(id);
            if (remove > 0) {
                return R.ok("删除成功");
            }
            return R.error("删除失败");
        }
        return R.error("非计划状态不能删除！");
    }

    /**
     * 审查
     */
    @EvApiByToken(value = "/apis/MoldingDaily/investigate", method = RequestMethod.GET, apiTitle = "审查成型日报")
    @ApiOperation("审查成型日报")
    public R investigate(@RequestParam("id") Long id) {

        UserDO userDO = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.WU_ID)){
            return R.error("操作对应人错误，请通知吴江海进行操作");
        }
        MoldingDailyDO moldingDailyDO = moldingDailyService.get(id);
        if(AslConstant.MoldingDailyStatus.PLAN.getType().equals(moldingDailyDO.getStatus())){
            return R.error("未提交，不能审查");
        }
        if (AslConstant.MoldingDailyStatus.AUDITOR.getType().equals(moldingDailyDO.getStatus())){
            return R.error("已审查，不能多次审查！");
        }
        if (AslConstant.MoldingDailyStatus.APPROVED.getType().equals(moldingDailyDO.getStatus())){
            return R.error("该表单已批准！");
        }
        moldingDailyDO.setStatus(AslConstant.MoldingDailyStatus.AUDITOR.getType());
        moldingDailyDO.setAuditorId(userDO.getUserId());
        moldingDailyDO.setAuditorName(userDO.getName());
        int update = moldingDailyService.update(moldingDailyDO);
        if (update > 0) {
            String title = "@我裁决的成型日报";
            UserDO user = userService.get(moldingDailyDO.getCreateBy());
            String content = "您好，"+user.getName()+"提交的成型日报已辅助裁决，请及时裁决";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",id);
            contentDetail.put("url","/jobShop/shapingDaily_add?id="+id+"&status="+moldingDailyDO.getStatus());
            HashMap<String, Object> userMap = new HashMap<>();
            userMap.put("deptId",1979);
            List<UserDO> list = userService.list(userMap);
            List<Long> toUsers = list.stream().filter(userDo -> userDo.getUserId() == 1977).map(UserDO::getUserId).collect(Collectors.toList());

            try {
                noticeService.saveAndSendSocket(title,content, id, contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送批准成型日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送批准成型日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            }

            return R.ok();
        }
        return R.error();
    }

    /**
     * 提交
     * @return
     */
    @EvApiByToken(value = "/apis/MoldingDaily/submitted",method = RequestMethod.POST,apiTitle = "提交成型日报")
    @ApiOperation("提交成型日报")
    @Transactional(rollbackFor = Exception.class)
    public R submitted( MoldingDailyDto dto){
            R r = R.error();
            if(ObjectUtils.isEmpty(dto.getId())){
                dto.setStatus(AslConstant.MoldingDailyStatus.SUBMITTED.getType());
                r = save(dto);
                MoldingDailyDO moldingDailyDO = moldingDailyService.get(dto.getId());
                UserDO user = userService.get(moldingDailyDO.getCreateBy());
                String title = "@我需要审查的成型日报";
                String content = "您好，"+user.getName()+"的成型日报填写完成，请及时辅助裁决";
                JSONObject contentDetail = new JSONObject();
                contentDetail.put("id",dto.getId());
                contentDetail.put("url","/jobShop/shapingDaily_add?id="+moldingDailyDO.getId()+"&status="+moldingDailyDO.getStatus());
                HashMap<String, Object> userMap = new HashMap<>();
                List<UserDO> list = userService.list(userMap);
                List<Long> toUsers = list.stream().filter(userDO -> userDO.getUserId()==272).map(UserDO::getUserId).collect(Collectors.toList());

                try {
                    noticeService.saveAndSendSocket(title,content, dto.getId(), contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
                } catch (IOException e) {
                    log.error("==============================发送辅助裁决成型日报的提醒消息失败。id:"+dto.getId());
                    throw new RuntimeException(e);
                } catch (ParseException e) {
                    log.error("==============================发送辅助裁决成型日报的提醒消息失败。id:"+dto.getId());
                    throw new RuntimeException(e);
                }
            }else{
                if(AslConstant.MoldingDailyStatus.SUBMITTED.getType().equals(dto.getStatus())){
                    return R.error("已提交，不能多次提交");
                }
                if(AslConstant.MoldingDailyStatus.AUDITOR.getType().equals(dto.getStatus())){
                    return R.error("已审查，不能提交");
                }
                if(AslConstant.MoldingDailyStatus.APPROVED.getType().equals(dto.getStatus())){
                    return R.error("已批准，不能提交");
                }
                dto.setStatus(AslConstant.MoldingDailyStatus.SUBMITTED.getType());
                UserDO user = userService.get(dto.getCreateBy());
                String title = "@我需要审查的成型日报";
                String content = "您好，"+user.getName()+"的成型日报填写完成，请及时辅助裁决";
                JSONObject contentDetail = new JSONObject();
                contentDetail.put("id",dto.getId());
                contentDetail.put("url","/jobShop/shapingDaily_add?id="+dto.getId()+"&status="+dto.getStatus());
                HashMap<String, Object> userMap = new HashMap<>();
                List<UserDO> list = userService.list(userMap);
                List<Long> toUsers = list.stream().filter(userDO -> userDO.getUserId()==272).map(UserDO::getUserId).collect(Collectors.toList());

                try {
                    noticeService.saveAndSendSocket(title,content, dto.getId(), contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
                } catch (IOException e) {
                    log.error("==============================发送辅助裁决成型日报的提醒消息失败。id:"+dto.getId());
                    throw new RuntimeException(e);
                } catch (ParseException e) {
                    log.error("==============================发送辅助裁决成型日报的提醒消息失败。id:"+dto.getId());
                    throw new RuntimeException(e);
                }
                r = this.update(dto);
            }

            MoldingProductionInstructionDO instructionDO = moldingProductionInstructionService.get(dto.getMpiId());

            Map<String, Object> params = Maps.newHashMapWithExpectedSize(5);
            params.put("materielId", instructionDO.getMaterielId());
            List<CheckResultDetail2VO> checkProjects = checkProjectService.list3(params);
            //生成检查成绩书
            CheckResultDO resultDO = new CheckResultDO();
            resultDO.setInstructionId(dto.getMpiId());
            resultDO.setInstructionNo(dto.getMpiNo());
            resultDO.setProductionDate(dto.getIndicateDate());
            resultDO.setProductId(instructionDO.getMaterielId());
            resultDO.setProduct(instructionDO.getMaterielName());
            resultDO.setInstructionQty(dto.getProductionQty());
            resultDO.setDailyNo(dto.getMpiNo());
            resultDO.setDailyId(dto.getId());
            resultDO.setBatchNo(ObjectUtils.isEmpty(dto.getLotNoStart()) ? "" : dto.getLotNoStart().substring(0,10));
            resultDO.setSpecification(dto.getSpecification());
//            String batchNo = (ObjectUtil.isEmpty(dto.getLotNoEnd()) ? "" : dto.getLotNoEnd()) + (ObjectUtil.isEmpty(dto.getLotNoStart()) ? "" : dto.getLotNoStart());
//            resultDO.setBatchNo(batchNo);
            if (!ObjectUtils.isEmpty(checkProjects)){
                checkResult(checkProjects,dto.getMGroup(),resultDO);
            }
        return r;
    }

    /**
     * 驳回
     * @return
     */
    @EvApiByToken(value = "/apis/MoldingDaily/overrule",method = RequestMethod.GET,apiTitle = "驳回成型日报")
    @ApiOperation("驳回成型日报")
    public R overrule(@ApiParam(value = "成型日报Id", required = true) @RequestParam("id") Long id){
        UserDO userDo = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.WU_ID)){
            return R.error("操作对应人错误，请通知吴江海进行操作");
        }
        MoldingDailyDO moldingDailyDO = moldingDailyService.get(id);
        if(AslConstant.MoldingDailyStatus.PLAN.getType().equals(moldingDailyDO.getStatus())){
            return R.error("未提交，不能驳回");
        }
        if(AslConstant.MoldingDailyStatus.AUDITOR.getType().equals(moldingDailyDO.getStatus())){
            return R.error("已审查，不能驳回");
        }
        if(AslConstant.MoldingDailyStatus.APPROVED.getType().equals(moldingDailyDO.getStatus())){
            return R.error("已批准，不能驳回");
        }
        moldingDailyDO
                .setStatus(AslConstant.MoldingDailyStatus.PLAN.getType());
        int update = moldingDailyService.update(moldingDailyDO);
        if(update>0){
            UserDO user = userService.get(moldingDailyDO.getCreateBy());
            String title = "@我需要修改的成型日报";
            String content = "您好，"+user.getName()+"的成型日报被驳回，请及时修改";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",id);
            contentDetail.put("url","/jobShop/shapingDaily_add?id="+id+"&status="+moldingDailyDO.getStatus());
            List<Long> toUsers = new ArrayList<>();
            toUsers.add(user.getUserId());

            try {
                noticeService.saveAndSendSocket(title,content, id, contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送驳回成型日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送驳回成型日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            }

            return R.ok();
        }
        return R.error();
    }
    /**
     * 反辅助裁决
     */
    @EvApiByToken(value = "/apis/MoldingDaily/antiInvestigate",method = RequestMethod.GET,apiTitle = "反辅助裁决成型日报")
    @ApiOperation("反辅助裁决成型日报")
    @Transactional(rollbackFor = Exception.class)
    public R antiInvestigate(@ApiParam(value = "成型日报Id", required = true) @RequestParam("id") Long id){
        UserDO userDo = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.JIN_ID)){
            return R.error("操作对应人错误，请通知金炯德进行操作");
        }
        MoldingDailyDO moldingDailyDO = moldingDailyService.get(id);
        if(AslConstant.MoldingDailyStatus.PLAN.getType().equals(moldingDailyDO.getStatus())){
            return R.error("未提交，不能反辅助裁决");
        }
        if(AslConstant.MoldingDailyStatus.SUBMITTED.getType().equals(moldingDailyDO.getStatus())){
            return R.error("未审查，不能反辅助裁决");
        }
        if(AslConstant.MoldingDailyStatus.APPROVED.getType().equals(moldingDailyDO.getStatus())){
            return R.error("已批准，不能反辅助裁决");
        }
        moldingDailyDO.setStatus(AslConstant.MoldingDailyStatus.SUBMITTED.getType());
        int update = moldingDailyService.update(moldingDailyDO);
        if(update>0){
            String title = "@我被反审的成型日报";
            UserDO user = userService.get(moldingDailyDO.getCreateBy());
            String content = "您好，"+user.getName()+"提交的成型日报被反审，请及时修正";
            JSONObject contentDetail = new JSONObject();
            contentDetail.put("id",id);
            contentDetail.put("url","/jobShop/shapingDaily_add?id="+id+"&status="+moldingDailyDO.getStatus());
            HashMap<String, Object> userMap = new HashMap<>();
            userMap.put("deptId",346);
            List<UserDO> list = userService.list(userMap);
            List<Long> toUsers = list.stream().filter(userDO -> userDO.getUserId()==272).map(UserDO::getUserId).collect(Collectors.toList());

            try {
                noticeService.saveAndSendSocket(title,content, id, contentDetail.toString(),55L,ShiroUtils.getUserId(),toUsers);
            } catch (IOException e) {
                log.error("==============================发送修改的成型日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            } catch (ParseException e) {
                log.error("==============================发送修改的成型日报的提醒消息失败。id:"+id);
                throw new RuntimeException(e);
            }

            return R.ok();
        }
        return R.error();
    }

    /**
     * 批准
     */
    @EvApiByToken(value = "/apis/MoldingDaily/ratify", method = RequestMethod.GET, apiTitle = "批准成型日报")
    @ApiOperation("批准成型日报")
    public R ratify(@ApiParam(value = "成型日报Id", required = true)  @RequestParam("id") Long id) {
        UserDO userDO = ShiroUtils.getUser();
        if(!ShiroUtils.isUser(AslConstant.JIN_ID)){
            return R.error("操作对应人错误，请通知金炯德进行操作");
        }
        MoldingDailyDO moldingDailyDO = moldingDailyService.get(id);
        if (AslConstant.MoldingDailyStatus.PLAN.getType().equals(moldingDailyDO.getStatus())){
            return R.error("未提交，不能批准！");
        }
        if(AslConstant.MoldingDailyStatus.SUBMITTED.getType().equals(moldingDailyDO.getStatus())){
            return R.error("未审查，不能批准！");
        }
        if (AslConstant.MoldingDailyStatus.APPROVED.getType().equals(moldingDailyDO.getStatus())){
            return R.error("已批准，不能多次批准！");
        }
        moldingDailyDO
                .setStatus(AslConstant.MoldingDailyStatus.APPROVED.getType());
        moldingDailyDO.setApproverId(userDO.getUserId());
        moldingDailyDO.setApproverName(userDO.getName());
        //TODO
        log.error("开始同步金蝶领料=====================================");
        Integer integer = moldingDailyService.syncSaveToK3(moldingDailyDO);
        if ( integer> 0){

            int update = moldingDailyService.update(moldingDailyDO);
            if (update > 0) {
                //将打码枪信息保存至     生产数量 - 不良数量
                BigDecimal multiply = null;
                if(ObjectUtils.isEmpty(moldingDailyDO.getProductionQty())){
                    multiply = BigDecimal.ZERO;
                }else if (ObjectUtils.isEmpty(moldingDailyDO.getInspectionQty())){
                    multiply = moldingDailyDO.getProductionQty();
                }else {
                    multiply = moldingDailyDO.getProductionQty().subtract(moldingDailyDO.getInspectionQty());
                }
                moldingBarcodeService.creatMoldingBarcode(id,moldingDailyDO.getMpiId(),multiply,moldingDailyDO.getMGroup(),1,moldingDailyDO.getCreateTime());
                moldingDailyService.update(moldingDailyDO);
                return R.ok();
            }
        }
        return R.error("未找到生产指示的生产计划");
//        int update = moldingDailyService.update(moldingDailyDO);
//        return R.ok();
    }

    /**
     * 查看成型日报分页列表
     * @param pageno
     * @param pagesize
     * @param delFlag
     * @param mpiNo
     * @param materielName
     * @param indicateDateStart
     * @param indicateDateEnd
     * @return
     */
    @EvApiByToken(value = "/apis/MoldingDaily/list", method = RequestMethod.POST, apiTitle = "查看成型日报分页列表")
    @ApiOperation("查看成型日报分页列表")
    public R list(@ApiParam(value = "当前第几页", required = true) @RequestParam(value = "pageno", defaultValue = "1") int pageno,
                  @ApiParam(value = "一页多少条", required = true) @RequestParam(value = "pagesize", defaultValue = "20") int pagesize,
                  @ApiParam(value = "刪除状态") @RequestParam(value = "delFlag", defaultValue = "", required = false) Integer delFlag,
                  @ApiParam(value = "生产指示编号") @RequestParam(value = "mpiNo", defaultValue = "", required = false) String mpiNo,
                  @ApiParam(value = "状态") @RequestParam(value = "status", defaultValue = "", required = false) Integer status,
                  @ApiParam(value = "品名") @RequestParam(value = "materielName", defaultValue = "", required = false) String materielName,
                  @ApiParam(value = "日期的起始时间") @RequestParam(value = "indicateDateStart", defaultValue = "", required = false) Date indicateDateStart,
                  @ApiParam(value = "日期的结束时间") @RequestParam(value = "indicateDateEnd", defaultValue = "", required = false) Date indicateDateEnd) {

        Map<String, Object> params = Maps.newHashMapWithExpectedSize(8);
        params.put("offset", (pageno - 1) * pagesize);
        params.put("limit", pagesize);
        params.put("delFlag", delFlag);
        params.put("status", status);
        params.put("mpiNo", mpiNo);
        params.put("materielName", materielName);
        params.put("indicateDateStart", indicateDateStart);
        params.put("indicateDateEnd", indicateDateEnd);

        Map<String, Object> results = Maps.newHashMapWithExpectedSize(1);
        List<Map<String, Object>> data = moldingDailyService.listForMap(params);

        if (data.size() > 0) {
            int total = moldingDailyService.countForMap(params);

            params.remove("offset");
            params.remove("limit");
            List<Map<String, Object>> data2 = moldingDailyService.listForMap(params);
            BigDecimal instructionQtyTotal = BigDecimal.ZERO;
            BigDecimal productionQtyTotal = BigDecimal.ZERO;
            BigDecimal inspectionQtyTotal = BigDecimal.ZERO;
            for (Map<String, Object> map : data2) {
                instructionQtyTotal = instructionQtyTotal
                        .add(new BigDecimal(String.valueOf(map.get("instructionQty") != null ? map.get("instructionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                productionQtyTotal = productionQtyTotal
                        .add(new BigDecimal(String.valueOf(map.get("productionQty") != null ? map.get("productionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                inspectionQtyTotal = inspectionQtyTotal
                        .add(new BigDecimal(String.valueOf(map.get("inspectionQty") != null ? map.get("inspectionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
            }

            for (Map<String,Object> map : data){
//                map.put("indicateDate", DateUtils.format((Date) map.get("indicateDate")));
                map.put("startDate", ObjectUtil.isEmpty(map.get("startDate")) ? null : DateUtils.format((Date) map.get("startDate"), "yyyy-MM-dd HH:mm:ss"));
                map.put("endDate", ObjectUtil.isEmpty(map.get("endDate")) ? null : DateUtils.format((Date) map.get("endDate"), "yyyy-MM-dd HH:mm:ss"));
            }

            Map<String, Object> result = Maps.newHashMapWithExpectedSize(4);
            result.put("data", new DsResultResponse(pageno, pagesize, total, data));
            result.put("instructionQtyTotal", instructionQtyTotal);
            result.put("productionQtyTotal", productionQtyTotal);
            result.put("inspectionQtyTotal", inspectionQtyTotal);
            results.put("data", result);
        }
        return R.ok(results);
    }


    @EvApiByToken(value = "/apis/MoldingDaily/list/exportExcel", method = RequestMethod.GET, apiTitle = "成型生产指示分页列表(导出)")
    @ApiOperation("成型生产指示分页列表(导出)")
    public void exportExcel(@ApiParam(value = "刪除状态") @RequestParam(value = "delFlag", defaultValue = "", required = false) Integer delFlag,
                            @ApiParam(value = "生产指示编号") @RequestParam(value = "mpiNo", defaultValue = "", required = false) String mpiNo,
                            @ApiParam(value = "品名") @RequestParam(value = "materielName", defaultValue = "", required = false) String materielName,
                            @ApiParam(value = "日期的起始时间") @RequestParam(value = "indicateDateStart", defaultValue = "", required = false) Date indicateDateStart,
                            @ApiParam(value = "日期的结束时间") @RequestParam(value = "indicateDateEnd", defaultValue = "", required = false) Date indicateDateEnd,
                            HttpServletRequest request, HttpServletResponse response,
                            ModelMap modelMap) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(5);
        params.put("delFlag", delFlag);
        params.put("mpiNo", mpiNo);
        params.put("materielName", materielName);
        params.put("indicateDateStart", indicateDateStart);
        params.put("indicateDateEnd", indicateDateEnd);
        List<Map<String, Object>> data = moldingDailyService.listForMap(params);
        if (!CollectionUtils.isEmpty(data)) {

            BigDecimal instructionQtyTotal = BigDecimal.ZERO;
            BigDecimal productionQtyTotal = BigDecimal.ZERO;
            BigDecimal inspectionQtyTotal = BigDecimal.ZERO;
            for (Map<String, Object> map : data) {
                map.put("indicateDateString", DateUtils.format((Date) map.get("indicateDate")));
                if (AslConstant.MoldingDailyStatus.PLAN.getType()
                        .equals(map.get("status"))) {
                    map.put("statusString", AslConstant.MoldingDailyStatus.PLAN.getName());
                }
                if (AslConstant.MoldingDailyStatus.AUDITOR.getType()
                        .equals(map.get("status"))) {
                    map.put("statusString",
                            AslConstant.MoldingDailyStatus.AUDITOR.getName());
                }
                if (AslConstant.MoldingDailyStatus.APPROVED.getType()
                        .equals(map.get("status"))) {
                    map.put("statusString",
                            AslConstant.MoldingDailyStatus.APPROVED.getName());
                }

                if (map.get("mGroup").equals(AslConstant.ZERO)){
                    map.put("mGroup", "A");
                }
                if (map.get("mGroup").equals(AslConstant.ONE)){
                    map.put("mGroup", "B");
                }
                if (map.get("mGroup").equals(AslConstant.TWO)){
                    map.put("mGroup", "C");
                }

                instructionQtyTotal = instructionQtyTotal
                        .add(new BigDecimal(String.valueOf(map.get("instructionQty") != null ? map.get("instructionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                productionQtyTotal = productionQtyTotal
                        .add(new BigDecimal(String.valueOf(map.get("productionQty") != null ? map.get("productionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
                inspectionQtyTotal = inspectionQtyTotal
                        .add(new BigDecimal(String.valueOf(map.get("inspectionQty") != null ? map.get("inspectionQty") : "0")))
                        .setScale(2, BigDecimal.ROUND_HALF_UP);
            }

            Map<String, Object> map = Maps.newHashMap();
            map.put("list", JSONUtils.format(data));
            map.put("instructionQtyTotal", instructionQtyTotal);
            map.put("productionQtyTotal", productionQtyTotal);
            map.put("inspectionQtyTotal", inspectionQtyTotal);

            ClassPathResource classPathResource = new ClassPathResource(
                    "poi/molding_daily.xlsx");
            TemplateExportParams result = new TemplateExportParams(classPathResource.getPath());
            modelMap.put(TemplateExcelConstants.FILE_NAME, "成型日报");
            modelMap.put(TemplateExcelConstants.PARAMS, result);
            modelMap.put(TemplateExcelConstants.MAP_DATA, map);
            PoiBaseView.render(modelMap, request, response,
                    TemplateExcelConstants.EASYPOI_TEMPLATE_EXCEL_VIEW);
        }
    }
}
